package access

import (
	"context"
	"myapp/internal/dao"
	"myapp/internal/model/do"
	"myapp/internal/model/entity"
	"myapp/internal/service"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
)

type sAccess struct{}

func init() {
	service.RegisterAccess(New())
}

func New() *sAccess {
	return &sAccess{}
}

func (u *sAccess) Create(ctx context.Context, in *entity.Access) (int64, error) {
	var err error
	if err = u.checkAccessMenu(ctx, in.RoleId, in.MenuId, 0); err != nil {
		return 0, err
	}
	result, err := dao.Access.Ctx(ctx).Data(do.Access{
		RoleId:     in.RoleId,
		MenuId:     in.MenuId,
		MenuLevel:  in.MenuLevel,
		MenuPid:    in.MenuPid,
		Module:     "",
		CreateTime: gtime.Now(),
	}).Insert()

	if err != nil {
		return 0, err
	}
	id, err := result.LastInsertId()
	return id, err
}

/**
 * 批量添加权限
 */
func (u *sAccess) CreateBatch(ctx context.Context, roleId uint, menuIds []uint) (err error) {
	_, err = dao.Access.Ctx(ctx).Where("role_id", roleId).Delete()
	if err != nil {
		return err
	}
	if len(menuIds) == 0 {
		return nil
	}

	menus, err := service.AdminMenu().GetMenus(ctx, menuIds)
	if err != nil {
		return nil
	}

	lst := make(g.List, 0, 32)
	for _, menu := range menus {
		var mp g.Map = g.Map{
			"role_id":     roleId,
			"menu_id":     menu.Id,
			"menu_level":  menu.Level,
			"menu_pid":    menu.Pid,
			"module":      "",
			"create_time": gtime.Now(),
		}
		lst = append(lst, mp)
	}

	_, err = dao.Access.Ctx(ctx).Data(lst).Insert()
	return err
}

// 获取一个角色的所有权限
func (u *sAccess) GetAccessByRoleId(ctx context.Context, roleId uint) ([]*entity.Access, error) {
	accessList := make([]*entity.Access, 0, 64)
	err := dao.Access.Ctx(ctx).Where("role_id", roleId).Limit(1000).Scan(&accessList)
	if err != nil {
		return nil, err
	}

	return accessList, err
}

// 检查用户名是否存在, 并排除自己
func (u *sAccess) checkAccessMenu(ctx context.Context, roleId, menuId, id uint) error {
	if roleId == 0 || menuId == 0 {
		return gerror.New("roleId,menuId参数不能为空")
	}
	m := dao.Access.Ctx(ctx).Where("role_id", roleId).Where("menu_id", menuId)
	if id > 0 {
		m = m.WhereNot("id", id)
	}
	count, err := m.Count()
	if err != nil {
		return err
	}
	if count > 0 {
		return gerror.New("此权限已经分配")
	}
	return nil
}
